package com.zoro.barn.business.service.sqldocument.business.document.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.zoro.barn.commons.db.autopage.PageList;
import com.zoro.barn.business.service.sqldocument.business.document.dto.BarnDocumentDto;
import com.zoro.barn.business.service.sqldocument.business.document.entity.BarnDocumentImage;
import com.zoro.barn.business.service.sqldocument.business.document.entity.BarnDocumentInfo;
import com.zoro.barn.business.service.sqldocument.business.document.entity.BarnDocumentUse;
import com.zoro.barn.business.service.sqldocument.business.document.service.BarnDocumentInfoService;
import com.zoro.barn.business.service.sqldocument.server.facade.BarnProductServerFacade;
import com.zoro.barn.business.service.sqldocument.server.facade.BarnProjectServerFacade;
import com.zoro.barn.business.service.sqldocument.server.facade.BarnUserServerFacade;
import com.zoro.barn.commons.tools.json.JsonUtil;
import com.zoro.barn.commons.webcommons.tools.WebContentUtil;
import com.zoro.barn.dto.system.BarnUserInfoDto;
import com.zoro.barn.dto.pp.product.BarnProductInfoDto;
import com.zoro.barn.dto.pp.project.BarnProjectInfoDto;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhaoxingwu
 */
@RestController
@RequestMapping("/document")
public class BarnDocumentInfoController {

    private final BarnDocumentInfoService barnDocumentInfoService;
    private final BarnProductServerFacade barnProductServerFacade;
    private final BarnProjectServerFacade barnProjectServerFacade;
    private final BarnUserServerFacade barnUserServerFacade;

    public BarnDocumentInfoController(BarnDocumentInfoService barnDocumentInfoService, BarnProductServerFacade barnProductServerFacade,
                                      BarnProjectServerFacade barnProjectServerFacade, BarnUserServerFacade barnUserServerFacade) {
        this.barnDocumentInfoService = barnDocumentInfoService;
        this.barnProductServerFacade = barnProductServerFacade;
        this.barnProjectServerFacade = barnProjectServerFacade;
        this.barnUserServerFacade = barnUserServerFacade;
    }

    @RequestMapping("/save")
    public BarnDocumentInfo save(@RequestBody BarnDocumentDto dto) throws JsonProcessingException {
        String userId = WebContentUtil.requestUserInfo().getPid();
        BarnDocumentInfo info = JsonUtil.transformType(dto, BarnDocumentInfo.class);
        if (StringUtils.isBlank(dto.getPid())) {
            info.setCreateId(userId);
            return this.barnDocumentInfoService.insert(info, dto.getDocumentText(), dto.getDocumentPlainText(), dto.getProjectIds(), dto.getImgIds());
        } else {
            return this.barnDocumentInfoService.update(info, dto.getDocumentText(), dto.getDocumentPlainText(), dto.getProjectIds(), dto.getImgIds());
        }
    }

    @RequestMapping("/queryMyDocument")
    public List<BarnDocumentDto> queryMyDocument(BarnDocumentInfo param) throws Exception {
        String pid = WebContentUtil.requestUserInfo().getPid();
        param.setCreateId(pid);
        List<BarnDocumentInfo> documentInfos = this.barnDocumentInfoService.query(param);
        List<BarnDocumentDto> result = PageList.fromCollection(documentInfos, BarnDocumentDto.class);
        fillProductName(result);
        return result;
    }

    @RequestMapping("/getById/{pid}")
    public BarnDocumentDto getById(@PathVariable("pid") String pid) throws Exception {
        BarnDocumentInfo info = this.barnDocumentInfoService.getById(pid);
        BarnDocumentDto result = JsonUtil.transformType(info, BarnDocumentDto.class);
        if (result == null) {
            return null;
        }
        // 查询正文
        if (StringUtils.isNotBlank(result.getFileId())) {
            String text = this.barnDocumentInfoService.getDocumentText(result.getFileId());
            result.setDocumentText(text);
        }
        // 查询project
        List<BarnDocumentUse> useList = this.barnDocumentInfoService.getDocumentUse(result.getPid());
        if (CollectionUtils.isNotEmpty(useList)) {
            String[] projectIds = useList.stream().map(BarnDocumentUse::getProjectId).distinct().toArray(String[]::new);
            Map<String, BarnProjectInfoDto> projectInfoDtoMap = this.barnProjectServerFacade.getByIds(projectIds);
            if (projectInfoDtoMap != null) {
                result.setProjects(projectInfoDtoMap.values().toArray(new BarnProjectInfoDto[0]));
            }
        }
        // productName
        if (StringUtils.isNotBlank(result.getProductId())) {
            Map<String, BarnProductInfoDto> productInfoDtoMap = this.barnProductServerFacade.getProductMap(new String[]{result.getProductId()});
            if (productInfoDtoMap != null && productInfoDtoMap.size() > 0) {
                BarnProductInfoDto dto = productInfoDtoMap.get(result.getProductId());
                if (dto != null) {
                    result.setProductName(dto.getProductName());
                }
            }
        }

        if (StringUtils.isNotBlank(result.getCreateId())) {
            List<BarnUserInfoDto> userInfoDtoList = this.barnUserServerFacade.getUserInfos(new String[]{result.getCreateId()});
            if (CollectionUtils.isNotEmpty(userInfoDtoList)) {
                BarnUserInfoDto dto = userInfoDtoList.get(0);
                result.setCreateUserName(dto.getUserName());
            }
        }

        // 查询image
        List<BarnDocumentImage> images = this.barnDocumentInfoService.getDocumentImages(result.getPid());
        if (CollectionUtils.isNotEmpty(images)) {
            List<String> imageIds = images.stream().map(BarnDocumentImage::getFileId).collect(Collectors.toList());
            result.setImgIds(imageIds.toArray(new String[1]));
        }
        return result;
    }

    @RequestMapping("/deleteById")
    public void deleteById(@RequestBody BarnDocumentInfo info) {
        this.barnDocumentInfoService.deleteDocument(info.getPid());
    }

    @RequestMapping("/query")
    public List<BarnDocumentDto> query(BarnDocumentDto param) throws Exception {

        // todo-future 这里在加入 elastic search 后应该使用 elastic 查询

        BarnDocumentInfo query = JsonUtil.transformType(param, BarnDocumentInfo.class);
        List<BarnDocumentInfo> documentInfos = this.barnDocumentInfoService.query(query);

        List<BarnDocumentDto> result = PageList.fromCollection(documentInfos, BarnDocumentDto.class);
        if (CollectionUtils.isNotEmpty(result)) {
            result.forEach(v -> {
                String fileId = v.getPlainTextId();
                String text = this.barnDocumentInfoService.getDocumentText(fileId);
                v.setDocumentPlainText(text == null ? "" : text.substring(0, Math.min(text.length(), 300)) + "...");
                List<BarnDocumentImage> images = this.barnDocumentInfoService.getDocumentImages(v.getPid());
                if (CollectionUtils.isNotEmpty(images)) {
                    String[] imgIds = images.stream().map(BarnDocumentImage::getFileId).distinct().toArray(String[]::new);
                    v.setImgIds(imgIds);
                }
            });
        }
        fillProductName(result);
        fillCreateName(result);
        return result;
    }

    /**
     * 查询 productName
     *
     * @param result document list
     * @throws Exception e
     */
    private void fillProductName(List<BarnDocumentDto> result) throws Exception {
        if (CollectionUtils.isNotEmpty(result)) {
            Map<String, BarnProductInfoDto> productMap =
                    barnProductServerFacade.getProductMap(result.stream().map(BarnDocumentDto::getProductId).distinct().toArray(String[]::new));
            if (productMap != null) {
                result.forEach(v -> {
                    BarnProductInfoDto dto = productMap.get(v.getProductId());
                    if (dto != null) {
                        v.setProductName(dto.getProductName());
                    }
                });
            }
        }
    }

    private void fillCreateName(List<BarnDocumentDto> result) throws Exception {
        if (CollectionUtils.isNotEmpty(result)) {
            String[] userIds = result.stream().map(BarnDocumentDto::getCreateId).distinct().toArray(String[]::new);
            if (userIds.length == 0) {
                return;
            }
            List<BarnUserInfoDto> userInfoDtoList = this.barnUserServerFacade.getUserInfos(userIds);
            if (CollectionUtils.isNotEmpty(userInfoDtoList)) {
                Map<String, String> userInfoDtoMap = userInfoDtoList.stream().collect(Collectors.toMap(BarnUserInfoDto::getPid, BarnUserInfoDto::getUserName, (a, b) -> b));
                result.forEach(v -> v.setCreateUserName(userInfoDtoMap.get(v.getCreateId())));
            }
        }
    }
}
